import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQml.Models 2.15
import QtQuick.Layouts 1.15

import org.ukui.systemTray 1.0
import org.ukui.publicItems 1.0

DropArea {
    id: dropArea
    property int itemWidth
    property int itemHeight
    property bool itemOrientation: true

    RowLayout {
        width: childrenRect.width
        height: childrenRect.height
        anchors.verticalCenter: parent.verticalCenter
        anchors.horizontalCenter: parent.horizontalCenter

        ListView {
            id: trayview
            property string idSelect: ""
            property bool isFold: false
            property int moveWidth: 0
            property int viewWidth: 0
            property int viewSpacing: 8
            Layout.preferredHeight: dropArea.itemOrientation ? dropArea.itemHeight : viewWidth
            Layout.preferredWidth: dropArea.itemOrientation ? viewWidth : dropArea.itemWidth
            orientation: dropArea.itemOrientation ? ListView.Horizontal : ListView.Vertical
            layoutDirection: ListView.RightToLeft
            verticalLayoutDirection: ListView.Qt.BottomToTop
            spacing: viewSpacing
            interactive: false

            Component.onCompleted: {
                var i = trayModel.count * (dropArea.itemWidth + trayview.viewSpacing);
                viewWidth = i;
            }

            displaced: Transition {
                ScriptAction {
                    script: {
                        trayview.viewWidth = trayModel.count * dropArea.itemWidth + trayModel.count * trayview.viewSpacing;
                    }
                }
                NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 }
                NumberAnimation { properties: "z"; to: 1; easing.type: Easing.OutQuad; duration: 1 }
            }
            move: Transition {
                ScriptAction {
                    script: {
                        trayview.viewWidth = trayModel.count * dropArea.itemWidth + trayModel.count * trayview.viewSpacing;
                    }
                }
                NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 }
                NumberAnimation { properties: "z"; to: 0; easing.type: Easing.OutQuad; duration: 1 }
            }
            remove: Transition {
                id: remTrans
                SequentialAnimation {
                    id: verRemTrans
                    ParallelAnimation {
                        NumberAnimation { properties: "opacity"; to: 0; duration: 200}
                        NumberAnimation { properties: dropArea.itemOrientation ? "x" : "y"; to: - trayview.moveWidth; easing.type: Easing.Bezier;
                                        easing.bezierCurve: [0.25, 0.1, 0.25, 1, 1, 1]; duration: 200 }
                        NumberAnimation { properties: "z"; to: -1; easing.type: Easing.OutQuad; duration: 1 }
                    }
                    ScriptAction {
                        script: {
                            trayview.viewWidth = trayModel.count * dropArea.itemWidth + trayModel.count * trayview.viewSpacing;
                        }
                    }
                }
            }
            add: Transition {
                SequentialAnimation {
                    NumberAnimation { properties: "z"; to: -1; easing.type: Easing.OutQuad; duration: 1 }
                    NumberAnimation { properties: dropArea.itemOrientation ? "x" : "y"; from: - trayview.moveWidth;easing.type: Easing.Bezier;
                                    easing.bezierCurve: [0.25, 0.1, 0.25, 1, 1, 1]; duration: 200 }
                    NumberAnimation { properties: "opacity"; to: 1; duration: 200}
                    NumberAnimation { properties: "z"; to: 1; easing.type: Easing.OutQuad; duration: 1 }
                }
            }
            model: DelegateModel {
                id: trayModel
                model: ItemModel

                groups: DelegateModelGroup {
                    name: "foldItems"
                    includeByDefault: false
                }
                delegate: DropArea {
                    property int visualIndex: DelegateModel.itemsIndex
                    width: dropArea.itemWidth
                    height: dropArea.itemHeight
                    clip: true

                    ListView.onAdd: {
                        trayview.viewWidth = trayModel.count * dropArea.itemWidth + trayModel.count * trayview.viewSpacing;
                    }

                    onEntered: {
                        if ((model.Type === ItemType.Fold) && trayview.isFold) {
                            control.isContain = true;
                        } else {
                            trayModel.items.move(drag.source.selectIndex, visualIndex);
                        }
                    }
                    onExited: {
                        control.isContain = false;
                    }
                    onDropped: {
                        if ((model.Type === ItemType.Fold) && trayview.isFold) {
                            control.isContain = false;
                            trayModel.items.move(drag.source.selectIndex, visualIndex);
                            trayModel.items.setGroups(drag.source.selectIndex, 1, trayModel.groups[2].name);
                            trayModel.groups[2].move(trayModel.groups[2].count - 1, 0);
                        }
                    }

                    Binding { target: control; property: "selectIndex"; value: visualIndex}
                    StyleBackground {
                        id: controlBase
                        clip: true
                        useStyleTransparency: false
                        anchors.fill: parent
                        paletteRole: Theme.BrightText
                        alpha: control.containsPress ? 0.1 : control.isContain ? 0.05 : 0

                        radius: 8
                        TrayIcon {
                            id: control
                            property int selectIndex: 0
                            property bool isContain: false
                            width: dropArea.itemWidth
                            height: dropArea.itemHeight
                            appStatus: model.Status
                            appAttentionMovieName: model.AttentionMovieName
                            appIcon: model.Icon
                            appAttentionIcon: model.AttentionIcon
                            appOverlayIcon: model.OverlayIcon
                            iconRotation: (model.Type === ItemType.Fold) ? appIconRotation() : 0

                            hoverEnabled: true
                            acceptedButtons: Qt.LeftButton | Qt.RightButton

                            Drag.active: drag.active
                            Drag.hotSpot.x: width / 2
                            Drag.hotSpot.y: height / 2
                            Drag.dragType: Drag.Automatic
                            Drag.onActiveChanged: {
                                if (Drag.active) {
                                    control.opacity = 0;
                                }
                            }

                            onEntered: {
                                isContain = true;
                            }
                            onExited: {
                                isContain = false
                            }
                            onCanceled: {
                                isContain = false
                            }
                            
                            onClicked: {
                                if (mouse.button === Qt.LeftButton) {
                                    if (model.Type === ItemType.Fold) {
                                        trayview.moveWidth = (visualIndex + 1) * (control.width + trayview.viewSpacing);
                                        if (trayview.isFold) {
                                            if (trayModel.groups[2].count !== 0) {
                                                trayModel.groups[2].setGroups(0, trayModel.groups[2].count, trayModel.groups[0].name);
                                            }
                                            trayview.isFold = false;
                                            trayview.viewWidth = trayModel.count * dropArea.itemWidth + trayModel.count * trayview.viewSpacing;
                                        } else {
                                            if (visualIndex !== trayModel.count - 1) {
                                                trayModel.items.setGroups(visualIndex + 1, trayModel.groups[0].count - visualIndex - 1, trayModel.groups[2].name);
                                            }
                                            trayview.isFold = true;
                                        }
                                    } else {
                                        trayModel.model.onActivate(index);
                                    }
                                }
                                if (mouse.button === Qt.RightButton) {
                                    trayModel.model.onContextMenu(index);
                                }
                            }

                            onPressed: {
                                if (model.Type === ItemType.Fold) return;
                                if (mouse.button === Qt.LeftButton) {
                                    trayview.idSelect = model.DataEngineSource;
                                    x = control.mapToItem(trayview,0,0).x;
                                    y = control.mapToItem(trayview,0,0).y;
                                    drag.target = control;
                                    control.parent = trayview;
                                    control.grabToImage(function(result) {
                                        control.Drag.imageSource = result.url;
                                    })
                                }
                            }
                            onReleased: {
                                Drag.drop();
                                drag.target = null;
                                control.parent = controlBase;
                                control.opacity = 1
                                x = 0;
                                y = 0;
                            }

                            function appIconRotation() {
                                if (panelOrientation) {
                                    return trayview.isFold ? 180 : 0;
                                } else {
                                    return trayview.isFold ? 270 : 90;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
